#include "math_3d.h"
#define GLEW_STATIC 1
#include <GL/glew.h>
#include <glut.h>
#include "Clock.h"
#include "Timer.h"
#include <assert.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "shader.hpp"
#include "config.h"
Timing::Clock clck;

#define FPS 60
#define TIMER_FREQ 1000/FPS


	
Timer timer;

GLfloat positions[] = {

	0.0f, 0.0f,0.0f,
	1.0f, 1.0f,0.0f,
	-1.0f, 1.0f,0.0f,
};

#if 0
	0.0f, 0.0f,0.0f,
	-1.0f, -1.0f,0.0f,
	1.0f, -1.0f,0.0f,
	
};
#endif

GLfloat colors[] = {

1.0f, 0.0f,0.0f,
	0.0f, 1.0f,0.0f,
	0.0f, 0.0f,1.0f,
};

#if 0
	0.0f,1.0f,0.0f,   // Color
	0.0f,0.0f,0.0f,   // Color
	0.0f,0.0f,0.0f,   // Color
};
#endif
GLushort indices[] = { 0,1,2};
#if 0
3,4,5};
#endif
GLuint vertexBufferId;
GLuint colorBufferId;
GLuint indexBufferId;

static void RenderSceneCB()
{

    glClear(GL_COLOR_BUFFER_BIT);
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

    //glDrawArrays(GL_TRIANGLES,0,6);
	glDrawElements(GL_TRIANGLES,3,GL_UNSIGNED_SHORT,0);
    glutSwapBuffers();
}

static int frameCount=0;
static void IdleFunction(void){
	float seconds = (float) timer.getElapsedTime();
	if(seconds > 1)
	{
		printf("FPS = %d\n",(int)(frameCount/seconds));
		frameCount = 0;
		timer.start();
	}
//	printf("%lf\n",timer.getElapsedTime());
	
	
	
	
}

static void CheckKeyState(void)
{

}


static void UpdateScene(int param)
{
	clck.newFrame();
	CheckKeyState();
	clck.timeElapsedLastFrame();

	/// Update any state of program



	// Request to Render it
	glutTimerFunc(TIMER_FREQ,UpdateScene,1);
	glutPostRedisplay();
	frameCount++;

}

void ReshapeWindow(int width, int height)
{
	glViewport(0,0,width,height);
	//printf("here\n");
}
static void InitializeGlutCallbacks()
{

    glutDisplayFunc(RenderSceneCB);
	glutIdleFunc(IdleFunction);
	glutTimerFunc(TIMER_FREQ,UpdateScene,1);
	glutReshapeFunc(ReshapeWindow);
	//glutKeyboardFunc(KeyboardHandler);
	//glutSpecialFunc(KeyboardHandler);
}


int OpenGLExample(int argc, char** argv)
{
	
    glutInit(&argc, argv);
		
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
    glutInitWindowSize(WIDTH, HEIGHT);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("Tutorial 03");

    InitializeGlutCallbacks();

    // Must be done after glut is initialized!
    GLenum res = glewInit();
	assert(GLEW_OK == res);
	assert(clck.initialize());
	
	glGenBuffers(1,&vertexBufferId);
	glBindBuffer(GL_ARRAY_BUFFER,vertexBufferId);
    glBufferData(GL_ARRAY_BUFFER,sizeof(positions),positions,GL_STATIC_DRAW);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,0);
 
	glGenBuffers(1,&colorBufferId);
	glBindBuffer(GL_ARRAY_BUFFER,colorBufferId);
    glBufferData(GL_ARRAY_BUFFER,sizeof(colors),colors,GL_STATIC_DRAW);
	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,0,0);
 
	
	//glEnableVertexAttribArray(1);
	//glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,sizeof(float)*6,(char *)(sizeof(float)*3));

	glGenBuffers(1,&indexBufferId);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,indexBufferId);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),indices,GL_STATIC_DRAW);
	
	GLuint program = LoadShaders("shaders\\basic.vs","shaders\\basic.fs");
	glUseProgram(program);
    
	timer.start();
    glutMainLoop();
	// Free all resources
	clck.shutdown();
	
    return 0;
}
